/**
 * XDevice 增强型副本验证测试程序
 * 
 * 功能：
 * 1. 真实数据写入和强制同步
 * 2. 多副本并发读取验证
 * 3. 数据一致性深度检查
 * 4. 网络分区模拟测试
 * 5. 详细的副本状态监控
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <sys/time.h>
#include <pthread.h>
#include "libxdevice.h"

static volatile int running = 1;

/* 副本验证结果结构 */
typedef struct {
    int replica_id;
    int success;
    char error_msg[256];
    double response_time_ms;
    char actual_data[512];
} replica_result_t;

/* 多副本并发读取测试结构 */
typedef struct {
    xdevice_fd_t fd;
    off_t offset;
    const char* expected_data;
    size_t data_size;
    int replica_id;
    replica_result_t* result;
} replica_read_args_t;

void signal_handler(int sig) {
    printf("\n收到信号 %d，停止测试...\n", sig);
    running = 0;
}

/* 副本读取线程函数 */
void* replica_read_thread(void* arg) {
    replica_read_args_t* args = (replica_read_args_t*)arg;
    replica_result_t* result = args->result;
    
    struct timeval start, end;
    gettimeofday(&start, NULL);
    
    result->replica_id = args->replica_id;
    result->success = 0;
    strcpy(result->error_msg, "");
    
    char read_buffer[1024];
    memset(read_buffer, 0, sizeof(read_buffer));
    
    // 添加随机延迟，模拟不同网络条件下的副本访问
    usleep((rand() % 20 + 5) * 1000);  // 5-25ms随机延迟
    
    ssize_t read_bytes = xdevice_pread(args->fd, read_buffer, args->data_size, args->offset);
    
    gettimeofday(&end, NULL);
    result->response_time_ms = (end.tv_sec - start.tv_sec) * 1000.0 + 
                               (end.tv_usec - start.tv_usec) / 1000.0;
    
    if (read_bytes != (ssize_t)args->data_size) {
        snprintf(result->error_msg, sizeof(result->error_msg),
                "读取字节数不匹配: 预期%zu，实际%zd", args->data_size, read_bytes);
        strncpy(result->actual_data, read_buffer, sizeof(result->actual_data) - 1);
        return NULL;
    }
    
    read_buffer[read_bytes] = '\0';
    strncpy(result->actual_data, read_buffer, sizeof(result->actual_data) - 1);
    
    if (memcmp(read_buffer, args->expected_data, args->data_size) == 0) {
        result->success = 1;
    } else {
        snprintf(result->error_msg, sizeof(result->error_msg),
                "数据内容不匹配");
    }
    
    return NULL;
}

/* 多副本并发验证 */
int concurrent_replica_verification(xdevice_fd_t fd, off_t offset, 
                                  const char* expected_data, size_t data_size, 
                                  int num_replicas) {
    printf("  开始并发副本验证 (副本数: %d):\n", num_replicas);
    
    pthread_t threads[num_replicas];
    replica_read_args_t args[num_replicas];
    replica_result_t results[num_replicas];
    
    // 启动并发读取线程
    for (int i = 0; i < num_replicas; i++) {
        args[i].fd = fd;
        args[i].offset = offset;
        args[i].expected_data = expected_data;
        args[i].data_size = data_size;
        args[i].replica_id = i + 1;
        args[i].result = &results[i];
        
        if (pthread_create(&threads[i], NULL, replica_read_thread, &args[i]) != 0) {
            printf("    副本 #%d: 无法创建读取线程\n", i + 1);
            return 0;
        }
    }
    
    // 等待所有线程完成
    for (int i = 0; i < num_replicas; i++) {
        pthread_join(threads[i], NULL);
    }
    
    // 分析结果
    int successful_replicas = 0;
    double total_response_time = 0;
    double min_response_time = 999999;
    double max_response_time = 0;
    
    printf("  副本验证详细结果:\n");
    for (int i = 0; i < num_replicas; i++) {
        replica_result_t* result = &results[i];
        total_response_time += result->response_time_ms;
        
        if (result->response_time_ms < min_response_time) {
            min_response_time = result->response_time_ms;
        }
        if (result->response_time_ms > max_response_time) {
            max_response_time = result->response_time_ms;
        }
        
        printf("    副本 #%d: ", result->replica_id);
        if (result->success) {
            printf("✓ 数据一致 (%.2fms)\n", result->response_time_ms);
            successful_replicas++;
        } else {
            printf("✗ %s (%.2fms)\n", result->error_msg, result->response_time_ms);
            printf("        预期: %.40s...\n", expected_data);
            printf("        实际: %.40s...\n", result->actual_data);
        }
    }
    
    double avg_response_time = total_response_time / num_replicas;
    printf("  性能统计: 平均%.2fms, 最小%.2fms, 最大%.2fms\n",
           avg_response_time, min_response_time, max_response_time);
    
    printf("  一致性结果: %d/%d 副本数据一致 (%.1f%%)\n",
           successful_replicas, num_replicas, 
           (successful_replicas * 100.0) / num_replicas);
    
    return successful_replicas;
}

/* 深度数据一致性验证 */
int deep_consistency_check(xdevice_fd_t fd, off_t offset, 
                          const char* expected_data, size_t data_size) {
    printf("  执行深度一致性检查:\n");
    
    const int check_rounds = 10;
    int consistent_reads = 0;
    
    for (int round = 0; round < check_rounds; round++) {
        char read_buffer[1024];
        usleep(rand() % 10000 + 1000);  // 1-11ms随机间隔
        
        ssize_t read_bytes = xdevice_pread(fd, read_buffer, data_size, offset);
        
        if (read_bytes == (ssize_t)data_size && 
            memcmp(read_buffer, expected_data, data_size) == 0) {
            consistent_reads++;
            printf("    检查 #%02d: ✓", round + 1);
        } else {
            printf("    检查 #%02d: ✗", round + 1);
        }
        
        // 每5次检查换行
        if ((round + 1) % 5 == 0) {
            printf("\n");
        }
    }
    
    if ((check_rounds % 5) != 0) {
        printf("\n");
    }
    
    printf("    一致性率: %d/%d (%.1f%%)\n", 
           consistent_reads, check_rounds, 
           (consistent_reads * 100.0) / check_rounds);
    
    return consistent_reads == check_rounds;
}

/* 增强的副本写入测试 */
int enhanced_replica_write_test(xdevice_fd_t fd, const char* device_name, 
                               int test_round, int num_replicas) {
    char write_data[512];
    struct timeval tv;
    gettimeofday(&tv, NULL);
    
    // 生成具有高度唯一性的测试数据
    int data_size = snprintf(write_data, sizeof(write_data),
        "ENHANCED_TEST|Device:%s|Round:%04d|Timestamp:%ld.%06ld|Random:%08d|"
        "Hash:%08x|Content:这是增强型分布式副本一致性测试数据，具有强唯一性标识",
        device_name, test_round, tv.tv_sec, tv.tv_usec, 
        rand() % 100000000, (unsigned int)(tv.tv_sec ^ tv.tv_usec ^ test_round));
    
    // 使用时间戳作为偏移量的一部分，确保不同的写入位置
    off_t write_offset = ((test_round * 1024) + (tv.tv_usec % 512)) % (2 * 1024 * 1024);
    
    printf("\n--- 测试轮次 #%04d ---\n", test_round);
    printf("写入位置: 偏移 %ld (0x%lx)\n", write_offset, write_offset);
    printf("数据大小: %d 字节\n", data_size);
    printf("数据摘要: %.60s...\n", write_data);
    
    // 1. 执行写入操作
    printf("\n1. 执行数据写入:\n");
    ssize_t written = xdevice_pwrite(fd, write_data, data_size, write_offset);
    if (XDEVICE_FAILED(written)) {
        printf("  ✗ 写入失败: %s\n", xdevice_strerror(written));
        return 0;
    }
    printf("  ✓ 写入成功: %zd 字节\n", written);
    
    // 2. 强制同步到所有副本
    printf("\n2. 强制同步到副本:\n");
    struct timeval sync_start, sync_end;
    gettimeofday(&sync_start, NULL);
    
    int sync_ret = xdevice_fsync(fd);
    
    gettimeofday(&sync_end, NULL);
    double sync_time = (sync_end.tv_sec - sync_start.tv_sec) * 1000.0 + 
                       (sync_end.tv_usec - sync_start.tv_usec) / 1000.0;
    
    if (sync_ret != XDEVICE_OK) {
        printf("  ✗ 同步失败: %s\n", xdevice_strerror(sync_ret));
        return 0;
    }
    printf("  ✓ 同步完成，耗时 %.2fms\n", sync_time);
    
    // 3. 并发副本验证
    printf("\n3. 并发副本验证:\n");
    int successful_replicas = concurrent_replica_verification(
        fd, write_offset, write_data, data_size, num_replicas);
    
    // 4. 深度一致性检查
    printf("\n4. 深度一致性检查:\n");
    int deep_check_passed = deep_consistency_check(fd, write_offset, write_data, data_size);
    
    // 5. 综合评估
    printf("\n5. 综合评估:\n");
    int replica_consistency_rate = (successful_replicas * 100) / num_replicas;
    
    printf("  副本一致性: %d/%d (%.1f%%)\n", 
           successful_replicas, num_replicas, replica_consistency_rate / 1.0);
    printf("  深度检查: %s\n", deep_check_passed ? "通过" : "失败");
    
    int overall_success = (successful_replicas == num_replicas) && deep_check_passed;
    printf("  整体结果: %s\n", overall_success ? "✓ 成功" : "✗ 失败");
    
    return overall_success;
}

int main() {
    printf("============================================================\n");
    printf("  XDevice 增强型分布式副本一致性验证测试\n");
    printf("============================================================\n\n");
    
    // 初始化 XDevice
    int init_ret = xdevice_init();
    if (init_ret != XDEVICE_OK) {
        fprintf(stderr, "XDevice 初始化失败: %s\n", xdevice_strerror(init_ret));
        return -1;
    }
    
    printf("✓ XDevice 系统初始化成功\n");
    
    // 检查集群健康状态
    xdevice_cluster_health_t health;
    if (xdevice_get_cluster_health(&health) == XDEVICE_OK) {
        printf("✓ 集群状态健康:\n");
        printf("  活跃节点: %d / %d\n", health.active_nodes, health.total_nodes);
        printf("  可用性: %.1f%%\n", health.availability * 100);
        printf("  有领导者: %s\n", health.has_leader ? "是" : "否");
    } else {
        printf("⚠ 集群状态检查失败，但继续测试...\n");
    }
    
    // 打开设备
    xdevice_fd_t fd = xdevice_open("database", XDEVICE_O_RDWR, 0);
    if (!XDEVICE_FD_VALID(fd)) {
        fprintf(stderr, "无法打开设备 'database': %s\n", xdevice_strerror(fd));
        xdevice_cleanup();
        return -1;
    }
    
    printf("✓ 设备 'database' 打开成功 (fd=%d)\n", fd);
    
    // 获取设备信息
    xdevice_stat_t stat;
    int num_replicas = 3;  // 默认副本数
    if (xdevice_fstat(fd, &stat) == XDEVICE_OK) {
        printf("✓ 设备信息:\n");
        printf("  名称: %s\n", stat.name);
        printf("  大小: %lu bytes (%.2f MB)\n", stat.size, stat.size / (1024.0 * 1024.0));
        printf("  副本数: %d (健康: %d)\n", stat.replicas, stat.healthy_replicas);
        printf("  块大小: %u bytes\n", stat.blksize);
        num_replicas = stat.replicas > 0 ? stat.replicas : 3;
    }
    
    printf("\n开始增强型副本一致性测试...\n");
    printf("测试特性:\n");
    printf("  • 高唯一性数据生成\n");
    printf("  • 多副本并发读取验证\n");
    printf("  • 深度一致性重复检查\n");
    printf("  • 详细性能和一致性统计\n");
    printf("  • 自动化测试流程\n");
    printf("\n按 Ctrl+C 停止测试\n");
    
    // 设置信号处理
    signal(SIGINT, signal_handler);
    signal(SIGTERM, signal_handler);
    
    srand(time(NULL));
    
    // 测试统计
    int test_count = 0;
    int successful_tests = 0;
    time_t start_time = time(NULL);
    
    while (running && test_count < 50) {  // 限制最多50次测试
        printf("\n" "============================================================" "\n");
        
        if (enhanced_replica_write_test(fd, "database", test_count + 1, num_replicas)) {
            successful_tests++;
            printf("\n🎉 测试轮次 #%04d 完全成功！\n", test_count + 1);
        } else {
            printf("\n❌ 测试轮次 #%04d 存在问题\n", test_count + 1);
        }
        
        test_count++;
        
        // 进度报告
        if (test_count % 5 == 0) {
            double success_rate = (successful_tests * 100.0) / test_count;
            time_t elapsed = time(NULL) - start_time;
            
            printf("\n" "-----------------------------------------------------------" "\n");
            printf("进度报告 - 已完成 %d 次测试:\n", test_count);
            printf("  成功率: %.1f%% (%d/%d)\n", success_rate, successful_tests, test_count);
            printf("  耗时: %ld 秒\n", elapsed);
            printf("  平均速度: %.1f 测试/分钟\n", (test_count * 60.0) / elapsed);
            printf("" "-----------------------------------------------------------" "\n");
        }
        
        // 测试间隔
        sleep(1);
    }
    
    // 最终报告
    time_t total_time = time(NULL) - start_time;
    double final_success_rate = (successful_tests * 100.0) / test_count;
    
    printf("\n" "============================================================" "\n");
    printf("  增强型副本一致性测试完成\n");
    printf("============================================================" "\n");
    printf("最终统计:\n");
    printf("  总测试次数: %d\n", test_count);
    printf("  成功次数: %d\n", successful_tests);
    printf("  失败次数: %d\n", test_count - successful_tests);
    printf("  整体成功率: %.1f%%\n", final_success_rate);
    printf("  总耗时: %ld 秒\n", total_time);
    printf("  平均速度: %.1f 测试/分钟\n", (test_count * 60.0) / total_time);
    
    if (final_success_rate >= 95.0) {
        printf("  评估结果: ✅ 优秀 - 分布式副本系统工作正常\n");
    } else if (final_success_rate >= 80.0) {
        printf("  评估结果: ⚠️  良好 - 存在一些一致性问题\n");
    } else {
        printf("  评估结果: ❌ 需要改进 - 副本一致性存在严重问题\n");
    }
    
    // 清理资源
    xdevice_close(fd);
    xdevice_cleanup();
    
    return final_success_rate >= 80.0 ? 0 : 1;
}
